//
//  Cliper.swift
//  chat
//
//  Created by 崔世强 on 2024/7/8.
//  Copyright © 2024 崔世强. All rights reserved.
//

import Foundation
import CryptoSwift

class Cipher {
    static let shared = Cipher(key: sec_key, iv: sec_iv)
    
    
    private let key: String
    private let iv: String
    
    init(key: String, iv: String) {
        self.key = key
        self.iv = iv
    }
    
    func encrypt(_ string: String) -> String? {
        do {
            let aes = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .pkcs7)
            let encryptedBytes = try aes.encrypt(Array(string.utf8))
            let encryptedData = Data(encryptedBytes)
            return encryptedData.base64EncodedString()
        } catch {
            print("Encryption error: \(error)")
            return nil
        }
    }
    
    func decrypt(_ string: String) -> String? {
        do {
            guard let data = Data(base64Encoded: string) else { return nil }
            let aes = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .pkcs7)
            let decryptedBytes = try aes.decrypt(Array(data))
            return String(bytes: decryptedBytes, encoding: .utf8)
        } catch {
            print("Decryption error: \(error)")
            return nil
        }
    }
    
    func encryptFile(atPath path: String, toEncryptedPath encryptedPath: String) throws {
        let fileData = try Data(contentsOf: URL(fileURLWithPath: path))
        
        let aes = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .pkcs7)
        let encryptedData = try aes.encrypt(Array(fileData))
        
        try Data(encryptedData).write(to: URL(fileURLWithPath: encryptedPath))
    }
    
    func decryptFile(atPath path: String, toDecryptedPath decryptedPath: String) throws {
        let encryptedData = try Data(contentsOf: URL(fileURLWithPath: path))
        
        let aes = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .pkcs7)
        let decryptedData = try aes.decrypt(Array(encryptedData))
        
        try Data(decryptedData).write(to: URL(fileURLWithPath: decryptedPath))
    }
    
    
    func encrypt(data: Data) throws -> Data {
        let aes = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .pkcs7)
        let encryptedData = try aes.encrypt(Array(data))
        return Data(encryptedData)
    }
    
    func decrypt(data: Data) throws -> Data {
        let aes = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .pkcs7)
        let decryptedData = try aes.decrypt(Array(data))
        return Data(decryptedData)
    }
    
}
